package com.fatcat.easybuy.service.impl;

import com.fatcat.easybuy.exception.BusinessException;
import com.fatcat.easybuy.mapper.EasyBuyProductMapper;
import com.fatcat.easybuy.pojo.EasyBuyOrder;
import com.fatcat.easybuy.pojo.EasyBuyOrderDetail;
import com.fatcat.easybuy.pojo.EasyBuyProduct;
import com.fatcat.easybuy.service.EasyBuyOrderDetailService;
import com.fatcat.easybuy.service.EasyBuyOrderService;
import com.fatcat.easybuy.service.EasyBuyProductService;
import com.fatcat.easybuy.service.ProductEsRepository;
import com.github.pagehelper.PageInfo;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Fatcat
 * @description 针对表【easybuy_product】的数据库操作Service实现
 * @createDate 2025-09-10 11:01:40
 */
@Service
public class EasyBuyProductServiceImpl implements EasyBuyProductService {
    @Autowired
    private ProductEsRepository elasticsearchRepository;
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    private EasyBuyProductMapper easyBuyProductMapper;
    @Autowired
    private EasyBuyOrderService easyBuyOrderService;
    @Autowired
    private EasyBuyOrderDetailService easyBuyOrderDetailService;
    @Autowired
    private RedisTemplate redisTemplate;

    private final String PREFIX_FAVORITE = "FavoriteList:";

    private static final Logger LOGGER = LoggerFactory.getLogger(EasyBuyProductServiceImpl.class);

    @Override
    public PageInfo<EasyBuyProduct> getAllProduct(Map<String, Object> params) {
        if (params.get("pageNum") == null || params.get("pageSize") == null) {
            throw new BusinessException("分页参数错误");
        }
        int pageNum = Integer.parseInt(params.get("pageNum").toString());
        int pageSize = Integer.parseInt(params.get("pageSize").toString());

        //查询生成器
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();
        //多条件查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("productName").preTags("<font style='color:#ff7800'>").postTags("</font>");
        //查询条件
        boolean isSearch = false;
        if (params.get("productName") != null) {
            boolQuery.must(QueryBuilders.matchQuery("productName", params.get("productName")).analyzer("ik_max_word"));
            isSearch = true;
        }
        if (params.get("startTime") != null && params.get("endTime") != null) {
            boolQuery.filter(QueryBuilders.rangeQuery("createTime").gte(params.get("startTime")).lte(params.get("endTime")).format("yyyy-MM-dd"));
            isSearch = true;
        }
        if (params.get("categoryLevel1Id") != null) {
            boolQuery.filter(QueryBuilders.matchQuery("categoryLevel1Id", params.get("categoryLevel1Id")));
            isSearch = true;
        }
        if (params.get("categoryLevel2Id") != null) {
            boolQuery.filter(QueryBuilders.matchQuery("categoryLevel2Id", params.get("categoryLevel2Id")));
            isSearch = true;
        }
        if (params.get("categoryLevel3Id") != null) {
            boolQuery.filter(QueryBuilders.matchQuery("categoryLevel3Id", params.get("categoryLevel3Id")));
            isSearch = true;
        }
        if (!isSearch) {
            searchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
        } else {
            searchQueryBuilder.withQuery(boolQuery);
        }
        searchQueryBuilder.withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC)).withPageable(PageRequest.of((pageNum - 1), pageSize)).withHighlightBuilder(highlightBuilder);
        SearchHits<EasyBuyProduct> searchHits = elasticsearchRestTemplate.search(searchQueryBuilder.build(), EasyBuyProduct.class);
        List<EasyBuyProduct> list = new ArrayList<>();

        for (SearchHit<EasyBuyProduct> hit : searchHits) {
            EasyBuyProduct easyBuyProduct = hit.getContent();
            Map<String, List<String>> highlightFields = hit.getHighlightFields();
            if (highlightFields.containsKey("productName")) {
                easyBuyProduct.setProductName(highlightFields.get("productName").get(0));
            }
            list.add(easyBuyProduct);
        }
        long total = searchHits.getTotalHits();
        int pages = (int) (total % pageSize == 0 ? total / pageSize : total / pageSize + 1);
        PageInfo<EasyBuyProduct> pageInfo = new PageInfo<>(list);
        pageInfo.setPages(pages);
        pageInfo.setTotal((int) total);
        pageInfo.setPageNum(pageNum);
        pageInfo.setPageSize(pageSize);
        return pageInfo;
    }

    @Override
    public List<EasyBuyProduct> getProductsByIds(List<Long> productIds) {
        if (productIds == null || productIds.isEmpty()) {
            throw new BusinessException("商品ID列表不能为空");
        }
        return easyBuyProductMapper.getProductsByIds(productIds);
    }

    @Transactional
    @Override
    public boolean addProduct(EasyBuyProduct product) {
        try {
            if (easyBuyProductMapper.addProduct(product) > 0) {
                // 新增成功后，同步到ES
                elasticsearchRepository.save(product);
                return true;
            }
            throw new BusinessException("新增商品失败");
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException("新增商品失败", e);
        }
    }

    @Transactional
    @Override
    public boolean updateProduct(EasyBuyProduct product) {
        try {
            if (easyBuyProductMapper.updateProduct(product) > 0) {
                // 更新成功后，同步到ES
                elasticsearchRepository.save(product);
                return true;
            }
            throw new BusinessException("更新商品失败");
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException("更新商品失败", e);
        }
    }

    @Transactional
    @Override
    public boolean deleteProduct(Long id) {
        try {
            // 删除商品前，先从ES中删除
            EasyBuyProduct product = getProductById(id);
            elasticsearchRepository.delete(product);
            if (easyBuyProductMapper.deleteProduct(id) > 0) {
                return true;
            }
            throw new BusinessException("删除商品失败");
        } catch (Exception e) {
            throw new BusinessException("删除商品失败", e);
        }
    }

    //根据id获取商品
    @Override
    public EasyBuyProduct getProductById(Long id) {
        if (id == null) {
            throw new BusinessException("商品ID不能为空");
        }
        EasyBuyProduct product = easyBuyProductMapper.selectProductById(id);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }
        return product;
    }

    //添加收藏
    @Override
    @Transactional
    public boolean addFavorite(Long userId, Long productId) {
        //检查商品是否被收藏
        if (isProductNotFavorited(userId, productId)) {
            //已收藏
            return true;
        }
        BoundListOperations<String, Object> listOperations = redisTemplate.boundListOps(PREFIX_FAVORITE + userId);
        Long size = listOperations.size();
        //如果长度为0直接添加
        if (size == null || size == 0) {
            listOperations.rightPush(productId);
            return true;
        }
        if (size >= 6) {
            //如果长度大于等于6，移除最左边的元素，添加到右边
            listOperations.leftPop();
            listOperations.rightPush(productId);
            return true;
        }
        if (listOperations.rightPush(productId) > 0) {
            return true;
        }
        return false;
    }

    //获取收藏
    @Override
    public List<Long> getFavoriteList(Long userId) {
        BoundListOperations<String, Object> listOperations = redisTemplate.boundListOps(PREFIX_FAVORITE + userId);
        List<Object> objects = listOperations.range(0, -1);
        List<Long> productIds = new ArrayList<>();
        for (Object object : objects) {
            productIds.add((Long) object);
        }
        return productIds;
    }

    //删除收藏
    @Override
    public boolean deleteFavorite(Long userId, Long productId) {
        BoundListOperations<String, Object> listOperations = redisTemplate.boundListOps(PREFIX_FAVORITE + userId);
        Long size = listOperations.size();
        //如果长度为0，直接返回false
        if (size == null || size == 0) {
            return false;
        }
        Long oprLine = redisTemplate.opsForList().remove(PREFIX_FAVORITE + userId, 1, productId);
        return oprLine != null && oprLine > 0;

    }

    //检查商品是否被收藏
    @Override
    public boolean isProductNotFavorited(Long userId, Long productId) {
        List<Long> productIds = getFavoriteList(userId);
        //检查是否存在
        return productIds.contains(productId);
    }

    @Transactional
    @Override
    public boolean updateProductTempStockByOutOrderNo(String outOrderNo) {
        //根据订单号获取订单详情
        EasyBuyOrder order = easyBuyOrderService.getOrderBySerialNumber(outOrderNo);
        //根据订单详情更新商品临时库存
        List<EasyBuyOrderDetail> orderDetailList = easyBuyOrderDetailService.getOrderDetailByOrderId(order.getId());
        //更新商品库存
        if (easyBuyProductMapper.updateProductTempStockByList(orderDetailList) <= 0) {
            //回滚临时库存
            throw new BusinessException("更新商品库存失败");
        }
        return true;
    }

    @Override
    public boolean updateProductTempStockRollbackByOutOrderNo(String outOrderNo) {
        //根据订单号获取订单详情
        EasyBuyOrder order = easyBuyOrderService.getOrderBySerialNumber(outOrderNo);
        //根据订单详情回滚临时库存
        List<EasyBuyOrderDetail> orderDetailList = easyBuyOrderDetailService.getOrderDetailByOrderId(order.getId());
        //回滚临时库存
        if (easyBuyProductMapper.rollbackProductTempStockByList(orderDetailList) <= 0) {
            throw new BusinessException("回滚临时库存失败");
        }
        return true;
    }

    @Transactional
    @Override
    public boolean updateProductStockByOutOrderNo(String outOrderNo) {
        //根据订单号获取订单详情
        EasyBuyOrder order = easyBuyOrderService.getOrderBySerialNumber(outOrderNo);
        //根据订单详情更新商品正式库存
        List<EasyBuyOrderDetail> orderDetailList = easyBuyOrderDetailService.getOrderDetailByOrderId(order.getId());
        //更新商品库存
        if (easyBuyProductMapper.updateProductStockByList(orderDetailList) <= 0) {
            //回滚正式库存
            throw new BusinessException("更新商品正式库存失败");
        }
        return true;

    }

    @Transactional
    @Override
    public boolean updateProductStockRollbackByOutOrderNo(String outOrderNo) {
        //根据订单号获取订单详情
        EasyBuyOrder order = easyBuyOrderService.getOrderBySerialNumber(outOrderNo);
        //根据订单详情回滚正式库存
        List<EasyBuyOrderDetail> orderDetailList = easyBuyOrderDetailService.getOrderDetailByOrderId(order.getId());
        //回滚正式库存
        if (easyBuyProductMapper.rollbackProductStockByList(orderDetailList) <= 0) {
            throw new BusinessException("回滚正式库存失败");
        }
        return true;
    }

    //检测是否存在商品该分类下
    @Override
    public boolean checkExitProductOfLevel1(Long id) {
        return easyBuyProductMapper.checkExitProductOfLevel1(id) > 0;
    }

    @Override
    public boolean checkExitProductOfLevel2(Long id) {
        return easyBuyProductMapper.checkExitProductOfLevel2(id) > 0;
    }

    @Override
    public boolean checkExitProductOfLevel3(Long id) {
        return easyBuyProductMapper.checkExitProductOfLevel3(id) > 0;
    }
}
